package com.itheima.server.service;

import cn.hutool.core.collection.CollUtil;
import com.itheima.autoconfig.template.OssTemplate;
import com.itheima.commons.utils.Constants;
import com.itheima.dubbo.api.CommentsApi;
import com.itheima.dubbo.api.MovementApi;
import com.itheima.dubbo.api.UserInfoApi;
import com.itheima.model.domain.UserInfo;
import com.itheima.model.enums.CommentType;
import com.itheima.model.mongo.Movement;
import com.itheima.model.vo.ErrorResult;
import com.itheima.model.vo.MovementsVo;
import com.itheima.model.vo.PageResult;
import com.itheima.server.exception.BusinessException;
import com.itheima.server.interceptor.UserHolder;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class MovementService {
    @Autowired
    private OssTemplate ossTemplate;
    @DubboReference
    private MovementApi movementApi;
    @DubboReference
    private UserInfoApi userInfoApi;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @DubboReference
    private CommentsApi commentsApi;

    /*发布动态*/
    public void publishMovement(Movement movement, MultipartFile imageContent[]) throws IOException {

        //判断动态信息是否为空
        if (StringUtils.isEmpty(movement.getTextContent())) {
            throw new BusinessException(ErrorResult.contentError());//内容错误
        }
        //获取当前用户的id
        Long userId = UserHolder.getUserId();
        //将文件上传到阿里云
        ArrayList<String> meidas = new ArrayList<>();
        for (MultipartFile multipartFile : imageContent) {

            String upload = ossTemplate.upload(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
            meidas.add(upload);
        }
        //封装成movment对象并调用api发布动态
        movement.setMedias(meidas);
        movement.setUserId(userId);
        movementApi.publish(movement);
    }

    /*查看我的动态*/
    public PageResult findByUserId(Long userId, Integer page, Integer pagesize) {
        //调用api查询个人动态
        PageResult pageResult = movementApi.findByUserId(userId, page, pagesize);
        //获取数据封将movement装为MovementVo对象(UserInfo和movment)
        UserInfo userInfo = userInfoApi.findById(userId);
        List<Movement> items = (List<Movement>) pageResult.getItems();
        ArrayList<MovementsVo> its = new ArrayList<>();
        for (Movement item : items) {
            MovementsVo movementsVo = MovementsVo.init(userInfo, item);
            its.add(movementsVo);
        }
        pageResult.setItems(its);
        return pageResult;
    }

    //查询好友动态
    public PageResult findFriendMovements(Integer page, Integer pagesize) {
        //获取当前用户id
        Long userId = UserHolder.getUserId();
        //调用api查询当前用户发布的动态列表
        List<Movement> movements = movementApi.findFriendMovements(userId, page, pagesize);
        return getPageResult(page, pagesize, movements);
    }

    /*推荐动态根据pids*/
    public PageResult findRecommendMovements(Integer page, Integer pagesize) {
        //先从redis中获取推荐数据(pids)
        String key = Constants.MOVEMENTS_RECOMMEND + UserHolder.getUserId();
        String value = redisTemplate.opsForValue().get(key);
        List<Movement> movements = Collections.EMPTY_LIST;//创建一个空的数组
        //判断数据是否存在
        if (StringUtils.isEmpty(value)) {
            //（不存在就要从api随机构造pagesize条数据）
            movements = movementApi.randomMovements(pagesize);
        } else {
            //存在，处理pid数据
            String[] values = value.split(",");
            if ((page - 1) * pagesize < values.length) {
                List<Long> pids = Arrays.stream(values).skip((page - 1) * pagesize).limit(pagesize).map(it -> Long.valueOf(it)).collect(Collectors.toList());
                //调用api根据pid数据查询动态数据
                movements = movementApi.findMovementsBypids(pids);
            }
        }

        return getPageResult(page, pagesize, movements);
    }

    /*根据movements查询相应的userInfo并成装成PageResult<MovementVo>*/
    public PageResult getPageResult(Integer page, Integer pagesize, List<Movement> movements) {
        //判断列表是否为空
        if (CollUtil.isEmpty(movements)) {
            return new PageResult();
        }
        //提取动态发布人的id列表
        List<Long> userId1 = CollUtil.getFieldValues(movements, "userId", Long.class);
        //根据用户的id列表获取用户详情
        Map<Long, UserInfo> userInfos = userInfoApi.findByIds(userId1, null);
        //构造vo对象
        List<MovementsVo> movementsVos = new ArrayList<>();
        for (Movement movement : movements) {
            UserInfo userInfo = userInfos.get(movement.getUserId());
            if (userInfo != null) {
                MovementsVo movementsVo = MovementsVo.init(userInfo, movement);
                //判断是否已经点赞(reids中)
                String key = Constants.MOVEMENTS_INTERACT_KEY + movement.getId();
                String hashKey = Constants.MOVEMENT_LIKE_HASHKEY + UserHolder.getUserId();
                //点赞过了就设置已点赞
                if (redisTemplate.opsForHash().hasKey(key, hashKey)) {
                    movementsVo.setHasLiked(1);
                }
                //判断是否喜欢
                String likekey = Constants.MOVEMENTS_INTERACT_KEY + movement.getId();
                String likehashKey = Constants.MOVEMENT_LOVE_HASHKEY + UserHolder.getUserId();
                if (redisTemplate.opsForHash().hasKey(likekey, likehashKey)) {
                    movementsVo.setHasLoved(1);
                }
                movementsVos.add(movementsVo);
            }
        }
        //构造PageResult
        PageResult pageResult = new PageResult(page, pagesize, (long) movementsVos.size(), movementsVos);
        return pageResult;
    }

    /*根据id查询动态详情*/
    public MovementsVo findById(String id) {
        Movement movement = movementApi.findById(id);
        if(movement==null){
            return null;
        }
        UserInfo userInfo = userInfoApi.findById(movement.getUserId());
        if(userInfo==null){
            return null;
        }
        return MovementsVo.init(userInfo, movement);

    }


}
